package org.ftc.report;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;

import org.apache.commons.lang3.StringUtils;
import org.docx4j.XmlUtils;
import org.docx4j.model.fields.merge.DataFieldName;
import org.docx4j.model.fields.merge.MailMerger;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.relationships.Namespaces;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;

public class Report14 {

	public static void main(String[] args) throws Exception {
		report14();
	}

	
	
	private static void report14() throws Exception	{
		File tmp = new File("D:\\ftc\\1165\\錄音清單.docx");
		WordprocessingMLPackage template = WordprocessingMLPackage.load(tmp);
		// 變數
		
		Map<DataFieldName,String> map = new HashMap<>();
		map.put(new DataFieldName("sessionNo"), "九九九九");
		map.put(new DataFieldName("date"), "103/1/1");
		
		
//		replaceTable("COLUMN1", map2, template);
		System.out.println("===================================");
		Part p  = template.getMainDocumentPart();
		List<Object> tables = getAllElementFromObject(p, Tbl.class);
		Tbl tempTable = getTemplateTable(tables,"提案單位");
		Map<String,String> map2 = new HashMap<>();
		map2.put("motionNo", "9999001");
		map2.put("unitName", "測試單位1");
		map2.put("cause", "測試用的案由102年1月32日ABCDEFG。");
		Map<String,String> map3 = new HashMap<>();
		map3.put("motionNo", "9999002");
		map3.put("unitName", "測試單位1");
		map3.put("cause", "測試用的案由。");
		Map<String,String> map4 = new HashMap<>();
		map4.put("motionNo", "9999301");
		map4.put("unitName", "測試單位1");
		map4.put("cause", "測試用的案由ABCDEFG。");
		Map<String,String> map5 = new HashMap<>();
		map5.put("motionNo", "9999404");
		map5.put("unitName", "測試單位1");
		map5.put("cause", "測試用的案由102年1月32日ABCDEFG測試用的案由102年1月32日ABCDEFG測試用的案由102年1月32日ABCDEFG測試用的案由102年1月32日ABCDEFG。");
		replaceAndAddTable(tempTable,Arrays.asList(map2,map3,map4,map5),template);
		
		MailMerger.performMerge(template, map, true);
//		WordprocessingMLPackage output = MailMerger.getConsolidatedResultCrude(template, Arrays.asList(map2,map7), true);
		template.save(new java.io.File("D:\\REPORT_14.docx"));
		System.out.println("end");
	}
	
	
	private static void replaceTable(String placeholders, Map<String, String> map,
			WordprocessingMLPackage template) throws Docx4JException, JAXBException {
		List<Object> tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class);
 
		// 1. find the table
		Tbl tempTable = getTemplateTable(tables, placeholders);
		List<Object> rows = getAllElementFromObject(tempTable, Tr.class);
		System.out.println("rows size:"+rows.size());
		// first row is header, second row is content
			// this is our template row
			Tr templateRow = (Tr) rows.get(0);
			List<?> textElements = getAllElementFromObject(templateRow, Text.class);
			for (Object object : textElements) {
				Text text = (Text) object;
				System.out.println("textValue:"+text.getValue());
				String value = map.get(text.getValue());
				text.setValue(StringUtils.isBlank(value)?"":value);
			}
			templateRow = (Tr) rows.get(1);
			textElements = getAllElementFromObject(templateRow, Text.class);
			for (Object object : textElements) {
				Text text = (Text) object;
				System.out.println("textValue:"+text.getValue());
				String value = map.get(text.getValue());
				text.setValue(StringUtils.isBlank(value)?"":value);
			}
	}
	
	private static void replaceAndAddTable(Tbl tempTable, List<Map<String, String>> textToAdd,
			WordprocessingMLPackage template) throws Docx4JException, JAXBException {
		// 1. find the table
		List<Object> rows = getAllElementFromObject(tempTable, Tr.class);
		System.out.println("rows size:"+rows.size());
			Tr templateRow = (Tr) rows.get(2);
			for (Map<String, String> replacements : textToAdd) {
				// 2 and 3 are done in this method
				addRowToTable(tempTable, templateRow, replacements);
			}
//			 4. remove the template row
			tempTable.getContent().remove(templateRow);
	}
	
	
	private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
		List<Object> result = new ArrayList<Object>();
		if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();
 
		if (obj.getClass().equals(toSearch))
			result.add(obj);
		else if (obj instanceof ContentAccessor) {
			List<?> children = ((ContentAccessor) obj).getContent();
			for (Object child : children) {
				result.addAll(getAllElementFromObject(child, toSearch));
			}
 
		}
		return result;
	}
	
	private static Tbl getTemplateTable(List<Object> tables, String templateKey) throws Docx4JException, JAXBException {
		for (Iterator<Object> iterator = tables.iterator(); iterator.hasNext();) {
			Object tbl = iterator.next();
			List<?> textElements = getAllElementFromObject(tbl, Text.class);
			for (Object text : textElements) {
				Text textElement = (Text) text;
				System.out.println("col value:"+textElement.getValue());
				if(StringUtils.equals(textElement.getValue(), templateKey))
					return (Tbl) tbl;
			}
		}
		return null;
	}
	
	private static void addRowToTable(Tbl reviewtable, Tr templateRow, Map<String, String> replacements) {
		Tr workingRow = (Tr) XmlUtils.deepCopy(templateRow);
		List<?> textElements = getAllElementFromObject(workingRow, Text.class);
		for (Object object : textElements) {
			Text text = (Text) object;
			System.out.println("textValue:"+text.getValue());
			String replacementValue = (String) replacements.get(text.getValue());
			if (replacementValue != null){
				System.out.println("replacement:"+replacementValue);
				text.setValue(replacementValue);
			}
		}
 
		reviewtable.getContent().add(workingRow);
	}

}
